package com.company

import java.io.File

fun main() {

    val p: Product = LuxureyProduct()
    println(p.load())

    //3、类型检测
    println(p is Product)
    println(p is LuxureyProduct)
    println(p is File)

    //4、类型转换：as
    if (p is LuxureyProduct) {
        println((p as LuxureyProduct).special())
    }
    //智能类型转换
    if (p is LuxureyProduct) {
        println(p.special())
    }

    //5、超类：Any  每一个类都会继承
    println(p is Any)
    println(p.toString())


    ApplicationConfig.doSomething()
    println(ApplicationConfig)
    println(ApplicationConfig)


    //对象表达式:需要某个类实例但只需用一次就行了。一旦实例化，匿名类只能有唯一一个实例存在
    val p2 = object : Product("jack") {
        override fun load() = "anonymous nothing..."
    }
    println(p2.load())

    //伴生对象  kotlin中没有static关键字
//    ConfigMap.load()


    //嵌套类
    Player.Equipment("Ak47").show()


    //数据类
    println(Coordinate(10, 20))
    //==比较的是内容  Any 默认实现===，比较的是引用
    //===比较的是引用
    println(Coordinate(10, 20) == Coordinate(10, 20))

    //解构声明  operator
    val (x, y) = Coordinate(60, 80)
    println("$x,$y")


    //copy
    val w = Worker("jack")
    val copy = w.copy("rose")  //这里有坑  copy的时候  没有用次构造函数  导致里面赋值的score没有生效
    println(w)
    println(copy)

    println(Direction.EAST)
}

//1、继承    类默认都是封闭的  若让某个类开放继承，使用open关键字
open class Product(var name: String) {
    fun description() = "Product：$name"

    open fun load() = "Nothing..."
}

//2、函数重载：父类的函数也要以open关键字修饰，子类才能覆盖它
class LuxureyProduct : Product("Luxurey") {
    override fun load() = "LuxureyProduct..."

    fun special() = "LuxureyProduct special function"
}


//6、object：只能产生一个实例的类-单例
//三种使用方式：对象声明   对象表达式   伴生对象
//对象声明
object ApplicationConfig {
    init {
        println("loadiing config...")
    }

    fun doSomething() {
        println("doSomething")
    }
}

//伴生对象
open class ConfigMap {
    companion object {
        private const val PAHT = "XXXXXX"
        fun load() = File(PAHT).readBytes()
    }
}

//7、嵌套类：
class Player {
    class Equipment(var name: String) {
        fun show() = println("equipment:$name")
    }

    fun battle() {
        Equipment("sharp knife").show()
    }
}


//8、数据类：存储数据的类  提供了toString实现
//使用数据类条件：
//1、必须有至少带一个参数的主构造函数
//2、主构造函数的参数必须是val或var
//3、数据类不能使用abstract,open,sealed,inner修饰符
data class Coordinate(var x: Int, var y: Int) {
    val isInBounds = x > 0 && y > 0
}


//9、data数据类的copy函数
data class Worker(var name: String, val age: Int) {
    var score = 10
    private val hobby = "music"
    val subject: String

    init {
        println("init Worker...")
        subject = "math"
    }

    constructor(_name: String) : this(_name, 50) {
        score = 80
    }

    override fun toString(): String {
        return "Worker(name='$name', age=$age, score=$score, hobby='$hobby', subject='$subject')"
    }

}

//运算符重载：operator

//10、枚举类  里面也可以定义函数
enum class Direction{
    EAST,
    WEST,
    SOUTH,
    NORTH
}

//11、密封类    sealed class Teacher{}






